home *** CD-ROM | disk | FTP | other *** search
/ ShareWare OnLine 2 / ShareWare OnLine Volume 2 (CMS Software)(1993).iso / prog / langwn23.zip / SAMPLE05.BAS < prev    next >
BASIC Source File  |  1993-03-20  |  24KB  |  644 lines

  1. '============================================================================
  2. '============================================================================
  3.  
  4. ' this sample has two demos:
  5. ' 1) subroutine IntButton illustrates the technique
  6. '    of starting a long running task and displaying an interrupt
  7. '    button to terminate that task. the "time out" feature of WinEvent is
  8. '    used to return control to your code if no events occur in 0.5 seconds.
  9.  
  10. ' 2) subroutine GetScrollDemo illustrates how to dynamically
  11. '    add text to a list of scrollable text in a visible window.
  12.  
  13. ' you must start QuickBASIC as follows:  qb /ah /L langwin
  14. '    /L langwin parameter provides access to LangWin quicklib
  15. '    /ah parameter is needed to allow dynamic arrays > 64k.
  16.  
  17.  
  18. DECLARE SUB IntButton ()      ' demo of interrupt button technique
  19. DECLARE SUB GrowScrollDemo () ' demo of adding text to visible window
  20. DECLARE FUNCTION VidType% ()  ' used to determine type of monitor
  21.  
  22. '  must compile with qb /ah /L langwin
  23.  
  24. '$DYNAMIC  make all arrays dynamic
  25.  
  26. DEFINT A-Z
  27.  
  28. '$INCLUDE: 'LANGWIN.BI' ' TYPE, DECLARE and COMMON definitions for LangWin.
  29. '                         NOTE: LANGWIN.BI contains all definitions found
  30. '                               in QB.BI, so include for QB.BI is not needed.
  31.  
  32.  
  33.  
  34. CLEAR , , 5000   ' set stack at 5000 bytes
  35.  
  36.  
  37. '---------------------------------------------------------------
  38. ' first see if EGA or VGA monitor
  39. mm = VidType
  40. IF mm <> 3 AND mm <> 4 THEN
  41.     ' monitor is not EGA/VGA
  42.     ' take whatever actions necessary (error messages)
  43.     BEEP
  44.     PRINT "LangWin needs EGA or VGA, sorry ........"
  45.     END
  46. END IF
  47.  
  48.  
  49. '-----------------------------------------------------------------
  50. ' get attribute from current screen (row 1, col 1)
  51. ' so it can be restored upon exit
  52. OrigAttr = SCREEN(1, 1, 1)
  53.  
  54. '-------------------------------------------------------------------
  55. ' if WIDTH command is used, it must be placed before call to LangWinInit
  56. ' because code in LangWinInit extracts max rows/cols from screen and saves
  57. ' in global variables. if WIDTH is used after LangWinInit, the global
  58. ' variable will not be set correctly.
  59. WIDTH 80, 25
  60.  
  61. '----------------------------------------------------------------------
  62. ' these variables MUST be defined BEFORE call to LangWinInit.
  63. ' keep these as low as possible to conserve memory at run time.
  64. MaxWindows = 8       ' max simultaneous open windows
  65. MaxButtons = 30      ' max number of objects (incl lines with labels) active
  66. MaxTextLines = 35    ' maximum number of text lines in any scrollable win
  67. MaxTextWins = 5      ' max windows that can have scrollable text
  68.                      ' must be <= MaxWindows
  69.  
  70. LOCATE , , 0         ' start with hidden text cursor
  71.  
  72. '---------------------------------------------------------------------------
  73. ' LangWin only supports text mode. You MUST call the SCREEN 0 command BEFORE
  74. ' the call to LangWinInit. You can call SCREEN with a video page other than 0
  75. ' (i.e., SCREEN 0,,x,x   where x is a page number supported by your system).
  76. ' Code in LangWinInit will determine which video page you are using and save
  77. ' the value in a global variable for use by other LangWin routines. If you
  78. ' call SCREEN 0 after LangWinInit and change the original video page, you'll
  79. ' get unpredictable results (i.e., LangWin will write to the original video
  80. ' page). However, you can use other video pages for functions not associated
  81. ' with your LangWin windows; just be sure to set the video page back to the
  82. ' original value defined below.
  83.  
  84. SCREEN 0, , 0, 0        ' LangWin ONLY supports text mode
  85.                         ' You MUST call the SCREEN command BEFORE LangWinInit
  86.  
  87.  
  88. CALL LangWinInit     ' initialize (if mouse exists, it will be displayed)
  89.               
  90.                      ' if you get "subscript out of range" error while
  91.                      ' in this routine, be sure you called QB with /ah.
  92.                      ' then try reducing the value of MaxWindows.
  93.                      ' check the WIDTH command; reduce number of columns,
  94.                      ' and/or number of rows.
  95.  
  96. '-----------------------------------------------------------------------
  97. ' display "wallpaper"
  98.  
  99. IF HaveMouse THEN CALL HideMouseCursor  ' first hide mouse pointer
  100.  
  101. CLS
  102. CALL SetColor(8, 15)
  103. FOR i = 1 TO MaxRows
  104. LOCATE i, 1
  105. PRINT STRING$(80, 178);     ' can try 176, 177, or 178
  106. NEXT
  107.  
  108. IF HaveMouse THEN CALL ShowMouseCursor   ' display the mouse pointer
  109.  
  110. '====================================================================
  111.  
  112. CALL IntButton        ' demo of technique to implement an interrupt button
  113. CALL GrowScrollDemo   ' demo of dynamically growing scrollable list
  114.  
  115. '=====================================================================
  116.  
  117.  
  118. IF HaveMouse THEN HideMouseCursor    ' we're done with the mouse
  119.  
  120. bbb = (OrigAttr AND &HF0) \ 16  ' mask & shift to get original background
  121. fff = OrigAttr AND &HF          ' mask to get original foreground
  122.  
  123.  
  124. PALETTE                           ' restore original palette
  125. CALL SetColor(fff, bbb)           ' restore orig foreground/background
  126. CLS
  127. LOCATE , , 1                      ' make text cursor visible
  128.  
  129.  
  130. END
  131.  
  132. REM $STATIC
  133. SUB GrowScrollDemo
  134.  
  135. ' this routine shows an example of how you could dynamically
  136. ' add text to the bottom of an existing window containing scrollable
  137. ' text (using the GrowScrollText function).
  138.  
  139. ' two windows are opened; one with buttons (EXIT, ADD, AUTO) and one
  140. ' with scrollable text.
  141.  
  142. ' for each click on ADD button, dynamic text will be manually generated and
  143. ' added to the bottom of the visible scrollable text. when the scrollable
  144. ' text fills the window, it is scrolled up as new text is added to the bottom.
  145. ' clicking the AUTO button will cause text to be automatically added.
  146. ' (a STOP button will become active. click it to halt the process;
  147. ' else process will halt when array is filled).
  148.  
  149. ' notice that the window to be modified (ie where the scrollable text
  150. ' is to be added) MUST be current when GrowScrollText is called.
  151. ' i've overlapped the text and buttons windows to show how the
  152. ' text window is given focus each time you click ADD to add a new line
  153. ' of text.
  154.  
  155. ' this technique could be used if your program searches a file, data base,
  156. ' directory, etc. for specific data, and you want to dynamically display
  157. ' the extracted info in a scrollable window as the search progresses.
  158. ' call GrowScrollText each time a new entry is returned by your search
  159. ' routine. this will give the user feedback - they'll see the scrollable text
  160. ' growing as new entries are found.
  161.  
  162. ' if you fill up the array (MaxTextLines), then GrowScrollText will
  163. ' return a -2 return code. in this case, you'll have to process
  164. ' the current array of scrollable text and perhaps give the
  165. ' user the option to continue the search (via a button) after
  166. ' all extracted data in this pass have been examined, etc.
  167.  
  168.  
  169.  
  170.  
  171. ' create a string array of scrollable text
  172. ' but it can be of size 1 since the LangWin structure SaveText
  173. ' and not the following array will actually hold the text being grown.
  174. DIM Text(1 TO 1) AS STRING
  175.  
  176. ' open a window with scrollable text
  177. w1 = OpenScrollWindow(3, 3, 21, 25, 3, 15, 2, 15, Text(), 1, 2, 17, 20, 0, 1)
  178.  
  179.  
  180. ' open window with control buttons
  181. w2 = BlankWin(4, 23, 12, 70, 9, 15, 2, 15, 0, 1)
  182.  
  183. x = ShowWinText(2, 3, 15, "Click ADD to manually add new text")
  184. x = ShowWinText(3, 3, 15, "Click AUTO to automatically add new text")
  185.  
  186.  
  187. ' make buttons.
  188. ' save handle numbers in variables.
  189. ' these will be used later to determine which button was clicked.
  190. xit1 = MakePushButton(5, 3, 6, "EXIT", 15, 4, 1)
  191. add1 = MakePushButton(5, 11, 5, "ADD", 15, 4, 1)
  192. auto1 = MakePushButton(5, 18, 6, "AUTO", 15, 4, 1)
  193. stop1 = MakePushButton(5, 26, 6, "STOP", 15, 4, 1)
  194. x = DeactivateButton(stop1, 1)  ' deactivate the stop button
  195.  
  196.  
  197. ' give the exit button focus (if ENTER is hit, EXIT button will be pushed)
  198. WinParms(CurWinPtr, 16) = xit1' put handle of exit button into data structure
  199. CALL ChangeButtonFocus(xit1, 0) ' reverse video the button to give it focus
  200.  
  201.  
  202.  
  203. '------------------------------------------------------------
  204. ' MAIN LOOP
  205. ' as long as any win is open
  206. ' wait for an event in any window, then process it
  207.  
  208. DO WHILE AnyWinOpen
  209.     ' wait for an event
  210.     ' win number (wn) and event code (action) returned
  211.     wn = WinEvent(action)
  212.  
  213.     ' test window number to see which window was current when event occurred
  214.     SELECT CASE wn
  215.  
  216.     CASE w2
  217.         ' determine what type of event occurred in the window w1
  218.         SELECT CASE action
  219.         CASE 1      ' close
  220.             xx = CloseWindow   ' close current window (with buttons)
  221.             xx = CloseWindow   ' only text win left, close it
  222.             EXIT DO
  223.  
  224.         CASE 3      ' button
  225.             ' see which button
  226.             SELECT CASE WinParms(CurWinPtr, 16)
  227.  
  228.             CASE xit1
  229.                 xx = CloseWindow   ' close current window (with buttons)
  230.                 xx = CloseWindow   ' only text win left, close it
  231.                 EXIT DO
  232.  
  233.             CASE add1
  234.                 T$ = "Time: " + TIME$  ' define new text
  235.                 ' must give text window focus BEFORE adding text
  236.                 IF IsWinOpen(w1, Han) THEN   ' get text win's handle
  237.                     CALL NewFocusWindow(Han) ' give text win focus
  238.                 END IF
  239.                 x = GrowScrollText(T$)       ' now add some text
  240.               
  241.                 ' test for errors
  242.                 SELECT CASE x
  243.                 CASE -1   ' no scrollable text
  244.                     ' process this condition
  245.                     ' usually it means you forgot to
  246.                     ' call NewFocusWindow to give focus to window
  247.                     ' with text to be modified.
  248.                 CASE -2
  249.                     ' scrollable text array was filled up.
  250.                     ' you'll probably have to activate a "continue" button,
  251.                     ' let the user view the text, and wait for an event.
  252.                     ' when the "continue" button is clicked,
  253.                     ' close the window with the full text array,
  254.                     ' open a new one in its place
  255.                     ' (with no text), and continue generating items
  256.                     ' to be displayed in the scrollable text window.
  257.               
  258.                     ' for the demo, i'll just make some noise
  259.                     ' to let you know array is full.
  260.                     BEEP
  261.                 END SELECT
  262.  
  263.             CASE auto1
  264.                 ' deactivate EXIT, ADD, and AUTO buttons
  265.                 x = DeactivateButton(xit1, 0)
  266.                 x = DeactivateButton(add1, 0)
  267.                 x = DeactivateButton(auto1, 0)
  268.                 ' activate the stop button
  269.                 x = ActivateButton(stop1, 0)
  270.                              
  271.                 ' must give text window (w1) focus BEFORE adding text.
  272.                 ' get it's handle, save in Han
  273.                 x = IsWinOpen(w1, Han)  ' get text win's handle
  274.               
  275.                 ' loop til STOP clicked or array is filled
  276.                 DO
  277.                     ' must give text window (w1) focus BEFORE adding text.
  278.                     ' window with buttons could be clicked while
  279.                     ' WinEvent has control for 0.5 sec, which would
  280.                     ' take focus away from the text window (w1) and give
  281.                     ' it to the window with buttons (w2). in this case,
  282.                     ' subsequent calls to GrowScrollText would return with
  283.                     ' a -1 return code. to prevent this condition,
  284.                     ' first make sure text window (w1) has focus.
  285.                     CALL NewFocusWindow(Han) ' give text win focus
  286.                    
  287.                     T$ = "Time: " + TIME$  ' define new text
  288.                     x = GrowScrollText(T$)       ' now add some text
  289.                     IF x = -2 THEN EXIT DO       ' bail out if array is full
  290.                     IF x = -1 THEN BEEP     ' this should not occur
  291.                     ' could insert a SLEEP 1 if necessary
  292.                     aa = -999   ' set "time out" option for WinEvent
  293.                     x = WinEvent(aa)  ' will return in 0.5 sec if no events occur
  294.                     ' loop until interrupt button is clicked
  295.                 LOOP UNTIL (aa = 3 AND WinParms(CurWinPtr, 16) = stop1)
  296.               
  297.                 BEEP ' make some noise
  298.  
  299.                 ' activate EXIT, ADD, and AUTO buttons
  300.                 x = ActivateButton(xit1, 0)
  301.                 x = ActivateButton(add1, 0)
  302.                 x = ActivateButton(auto1, 0)
  303.                 ' deactivate the stop button
  304.                 x = DeactivateButton(stop1, 0)
  305.  
  306.             END SELECT   ' end of code to process buttons
  307.  
  308.         END SELECT   ' end of code to process actions in the window
  309.  
  310.  
  311.     END SELECT   ' end of code that processes windows
  312. LOOP
  313.      
  314. LOCATE 25, 1
  315. CALL SetColor(15, 4)
  316. PRINT "HIT ANY KEY TO CONTINUE DEMO ...";
  317. SLEEP
  318.  
  319. LOCATE 25, 1
  320. CALL SetColor(8, 15)
  321. PRINT STRING$(80, 178);
  322.  
  323. END SUB
  324.  
  325. '
  326. '  this subroutine illustrates the technique of opening a window,
  327. '  starting a long running task in a loop, and implementing an
  328. '  interrupt button to terminate the task.
  329. '
  330. '  the "time out" option of WinEvent is used in the loop with the long
  331. '  running task. after a portion of the task is completed, control
  332. '  is given to WinEvent to determine if any actions have occured in
  333. '  the window. if an action occurs, WinEvent will return control as usual.
  334. '  if no actions occur in 0.5 sec, WinEvent times out and returns control
  335. '  to your code. when you get control, test to see if any actions have
  336. '  occured. if none, loop and do more work on the task at hand. if
  337. '  an action occured (i.e., the interrupt button pressed), then
  338. '  terminate the task by exiting the loop.
  339. '
  340. SUB IntButton
  341.  
  342.  
  343.  
  344. '=============================================================
  345. ' main window: text and buttons
  346. m1 = BlankWin(9, 26, 21, 69, 9, 15, 1, 0, 1, 1)
  347. ' i'll skip the test for an error return code
  348.  
  349. ' display some text in the window
  350. d = ShowWinText(1, 2, 15, "Example of 'time out' option in WinEvent")
  351. d = ShowWinText(2, 2, 15, "to implement an INTERRUPT button.")
  352. d = ShowWinText(4, 2, 15, "Click Test Win button to open window.")
  353. d = ShowWinText(5, 2, 15, "Click Start button to begin task.")
  354. d = ShowWinText(6, 2, 15, "Click Interrupt button to terminate task.")
  355. ' put a title in window
  356. d = ShowTitle(" SAMPLE05 ", 15, 4)
  357. ' no error tests will done for above functions
  358.  
  359. ' make buttons.
  360. ' save handle numbers in variables.
  361. ' these will be used later to determine which button was clicked.
  362. TestWin = MakePushButton(8, 10, 10, "Test Win", 15, 3, 1)
  363. xit2 = MakePushButton(8, 23, 6, "EXIT", 15, 5, 1)
  364.  
  365. ' give the exit button focus (if ENTER is hit, EXIT button will be pushed)
  366. WinParms(CurWinPtr, 16) = xit2' put handle of exit button into data structure
  367. CALL ChangeButtonFocus(xit2, 0) ' reverse video the button to give it focus
  368.  
  369. '=============================================================
  370.  
  371.  
  372. ' MAIN LOOP
  373. ' as long as any win is open
  374. ' wait for an event in any window, then process it
  375.  
  376. DO WHILE AnyWinOpen
  377.     ' wait for an event
  378.     ' win number (wn) and event code (action) returned
  379.     wn = WinEvent(action)
  380.  
  381.     ' test window number to see which window was current when event occurred
  382.     SELECT CASE wn
  383.  
  384.     CASE m1      ' main window
  385.         ' now determine what type of event occurred in the window w2
  386.         SELECT CASE action
  387.         CASE 1      ' close icon or ESC
  388.             x = CloseWindow
  389.         CASE 2      ' text
  390.             ' no scrollable text to select in this win
  391.         CASE 3      ' button
  392.             ' determine which button was clicked
  393.    
  394.             ' get handle number of clicked button
  395.             ButtonHandle = WinParms(CurWinPtr, 16)
  396.  
  397.             ' test all buttons for match
  398.             SELECT CASE ButtonHandle
  399.             CASE xit2   ' exit
  400.                 xx = CloseWindow
  401.  
  402.             CASE TestWin  ' test window button
  403.                
  404.                 ' open a MODAL window to illustrate use of WinEvent's
  405.                 ' "time out" option for implementing an interrupt button.
  406.                 ' i strongly recommend that the window containing
  407.                 ' the interrupt button be MODAL (otherwise your user
  408.                 ' could attempt to mouse to another window and click buttons).
  409.                
  410.                 ' since this will be a modal window,
  411.                 ' actions on other windows will be ignored until this win
  412.                 ' closed. thus, there is no need to deactivate buttons
  413.                 ' in the main window to prevent the user opening another
  414.                 ' instance of the test window. the fact that this is a modal
  415.                 ' window will insure that all objects in other windows
  416.                 ' are ignored. we will still have to deactivate some objects
  417.                 ' in this window that should be ignored.
  418.  
  419.                 win1 = BlankWin(3, 3, 12, 40, 5, 15, 1, 0, 0, 2)
  420.                 ' i'll skip test for return code with error
  421.                
  422.                 ' put some text into the window
  423.                 d = ShowWinText(2, 3, 14, "Interrupt Button Example")
  424.                 ' make some buttons
  425.                 w1strt = MakePushButton(7, 3, 7, "START", 15, 3, 1)
  426.                 w1int = MakePushButton(7, 13, 11, "INTERRUPT", 15, 3, 1)
  427.                 w1xit = MakePushButton(7, 27, 6, "EXIT", 15, 3, 1)
  428.                 
  429.                 ' initially, the interrupt button is inactive
  430.                 d = DeactivateButton(w1int, 0)
  431.                
  432.                 ' i'll use a technique explained in SAMPLE04 to determine
  433.                 ' the handle of a static text field, and re-use that
  434.                 ' handle to dynamically change text in the window.
  435.                 ' this will show progress that is being made in the
  436.                 ' in the window while waiting for the interrupt button
  437.                 ' to be clicked.
  438.                
  439.                 x = ShowWinText(4, 3, 15, "KNOWN VALUE")  ' known text
  440.                 ' now scan all button text to find handle of above text
  441.                 timhan = -999               ' default handle number
  442.                 FOR i = 1 TO MaxButtons    ' scan the entire data structure
  443.                   IF ButtonsText(i) = "KNOWN VALUE" THEN  ' look for text
  444.                     timhan = i                    ' if match, save handle
  445.                     EXIT FOR                      ' terminate search
  446.                   END IF
  447.                 NEXT
  448.                 ' this problem should not occur
  449.                 ' (ie, could not find specific text in ButtonsText array),
  450.                 ' but as safety valve, i'll test for it.
  451.                 IF timhan = -999 THEN END
  452.  
  453.                 ' at this point, timhan contains handle of text object
  454.                 ' that will by dynamically changed
  455.                 ButtonsText(timhan) = ""      ' initialize text
  456.                 CALL ReShowInputField(timhan)  ' update screen
  457.                 ButtonsData(timhan, 4) = LEN(a$)  ' update length of area
  458.                
  459.                 ' now return to main loop and wait for an event in the
  460.                 ' window just opened.
  461.  
  462.             END SELECT ' end of select for buttons in main
  463.         END SELECT  ' end of select for main window
  464.  
  465.     CASE win1        ' window where interrupt button is to be used
  466.        
  467.         ' only button events possible (no other objects defined)
  468.         ' determine which button caused the event
  469.  
  470.         SELECT CASE WinParms(CurWinPtr, 16)
  471.  
  472.         CASE w1strt   ' start button
  473.             ' clicking the start button will begin a sample long running task.
  474.             ' in my example, only the interrupt button will terminate
  475.             ' the task. your code could implement a task that might terminate
  476.             ' nornally if it ran long enough (like reading records from a
  477.             ' file) or terminate immediately (if interrupt button is clicked).
  478.            
  479.             ' when the start button is clicked, the text label
  480.             ' will be dynamically updated with the current time to simulate
  481.             ' a task being done in a window while waiting for an
  482.             ' interrupt button to be clicked.
  483.  
  484.             'deactivate the start and exit buttons
  485.             d = DeactivateButton(w1strt, 0)  ' deactivate the start button
  486.             d = DeactivateButton(w1xit, 0)   ' deactivate the exit button
  487.             'activate the interrupt button
  488.             d = ActivateButton(w1int, 0)     ' activate the interrupt button
  489.  
  490.            
  491.             ' to implement the technique of waiting for an interrupt button,
  492.             ' a loop is used where some portion of the task is done
  493.             ' (like reading one record from a file, scanning one directory,
  494.             ' etc.), then WinEvent is called with the action parameter set to
  495.             ' -999. this will cause WinEvent to "time out" and return
  496.             ' after 0.5 sec if no event is detected, that is WinEvent will
  497.             ' return control after 0.5 sec if the interrupt button was
  498.             ' not clicked (if an event is detected, WinEvent will return as
  499.             ' soon as the event is processed). when control is returned, just
  500.             ' test to see if an event occured and if it was the interrupt
  501.             ' button. if no event occured, continue with the loop and
  502.             ' process the next portion of the task at hand. if the task
  503.             ' completes nornally, or if you detect that the interrupt button
  504.             ' was clicked when returning from WinEvent, then exit the loop.
  505.            
  506.             ' in this example, i just loop and modify the text field with
  507.             ' current time (to simulate a long running task).
  508.             ' when the INTERRUPT button is clicked, processing will stop.
  509.             ' there is no test for nornal completion of the simulated task.
  510.  
  511.             DO       ' the long running task loop
  512.                 ' simulate some work
  513.                 ButtonsText(timhan) = TIME$   'place current time in array
  514.                 CALL ReShowInputField(timhan) 'update screen to show progress
  515.                 ButtonsData(timhan, 4) = LEN(a$)  ' update length of area
  516.                
  517.                 ' since the previous commands to update text on the screen
  518.                 ' are so fast, i've included the following SLEEP command
  519.                 ' to simulate the long running task's work within the loop.
  520.                 ' change the amount of time to sleep to see the effect.
  521.                
  522.                 ' unfortunately, mouse clicks made while work is done outside
  523.                 ' of WinEvent are not "remembered" when WinEvent gets control.
  524.                 ' this is because WinEvent hides/shows the mouse cursor
  525.                 ' which resets the press counter. thus, if the loop you
  526.                 ' implement (with work and a call to WinEvent) takes a long
  527.                 ' time to get back to WinEvent each time, the effect will be
  528.                 ' that clicks on the interrupt button may seem to be ignored.
  529.                 ' your user will have to click repeatedly on the interrupt
  530.                 ' button (to make sure that at least one of those clicks
  531.                 ' occurs while EinEvent has control). to see this effect,
  532.                 ' set the wait time in the following SLEEP command to 5
  533.                 ' or more. you'll have to click frequently on the interrupt
  534.                 ' button. sorry, i never said LangWin was perfect!
  535.                
  536.                 ' to avoid this situation, try to keep the amount of work
  537.                 ' done in your loop as short (or efficient) as possible.
  538.                 ' add a SLEEP x command below to see effects of processing
  539.                 ' delays in the loop with WinEvent.
  540.                
  541.                 aa = -999   ' set "time out" option for WinEvent
  542.                 x = WinEvent(aa)  ' will return in 0.5 sec if no events occur
  543.                 ' loop until interrupt button is clicked
  544.             LOOP UNTIL aa = 3 AND WinParms(CurWinPtr, 16) = w1int
  545.  
  546.             ' processing was interrupted
  547.             ' activate start and exit buttons and deactivate interrupt button
  548.             d = ActivateButton(w1strt, 0)  ' activate the start button
  549.             d = ActivateButton(w1xit, 0)   ' activate the exit button
  550.             d = DeactivateButton(w1int, 0) ' deactivate the interrupt button
  551.        
  552.         CASE w1xit   ' exit button
  553.             x = CloseWindow
  554.        
  555.         END SELECT   ' end of section to process events in modal window
  556.  
  557.  
  558.     END SELECT
  559.  
  560.  
  561. LOOP
  562.  
  563. LOCATE 25, 1
  564. CALL SetColor(15, 4)
  565. PRINT "HIT ANY KEY TO CONTINUE DEMO ...";
  566. SLEEP
  567.  
  568. LOCATE 25, 1
  569. CALL SetColor(8, 15)
  570. PRINT STRING$(80, 178);
  571.  
  572. END SUB
  573.  
  574. ' =====================================================
  575. '  returns type of video display
  576. '
  577. '  return values:
  578. '       1:  black/white    (could be EGA/VGA with monochrome)
  579. '       2:  CGA   (with color)
  580. '       3:  EGA   (with color)
  581. '       4:  VGA   (with color)
  582. '       5:  MCGA  (with color)
  583. '      99:  other
  584. '
  585. FUNCTION VidType
  586.  
  587. ' quick & dirty, check &h463
  588. DEF SEG = 0
  589. IF PEEK(&H463) = &HB4 THEN     ' see if monochrome
  590.     VidType = 1
  591.     EXIT FUNCTION
  592. END IF
  593. DEF SEG
  594.  
  595. ' first try int 10h, function 1Ah
  596.  
  597. InRegs.ax = &H1A00
  598. CALL INTERRUPTX(&H10, InRegs, OutRegs)
  599. IF (OutRegs.ax AND &HFF) = &H1A THEN    ' see if int 10h, funct 1Ah supported
  600.     code = (OutRegs.bx AND &HFF)  ' get display code
  601.     SELECT CASE code
  602.     CASE 1      ' MDA
  603.         VidType = 1
  604.     CASE 2      ' CGA
  605.         VidType = 2
  606.     CASE 4      ' EGA color
  607.         VidType = 3
  608.     CASE 5      ' EGA b/w
  609.         VidType = 1
  610.     CASE 7      ' VGA b/w
  611.         VidType = 1
  612.     CASE 8      ' VGA color
  613.         VidType = 4
  614.     CASE 10     ' MCGA color
  615.         VidType = 5
  616.     CASE 11     ' MCGA b/w
  617.         VidType = 1
  618.     CASE ELSE
  619.         VidType = 99    ' other
  620.     END SELECT
  621.     EXIT FUNCTION
  622.  
  623. ELSE
  624.     ' now try int 10h, function 12h, sub-function 10h
  625.     InRegs.ax = &H1200
  626.     InRegs.bx = &H10
  627.     CALL INTERRUPTX(&H10, InRegs, OutRegs)
  628.     IF (OutRegs.bx AND &HFF00) = 1 THEN     ' see if monochrome
  629.         VidType = 1
  630.         EXIT FUNCTION
  631.     END IF
  632.  
  633.     IF (OutRegs.bx AND &HFF) <> &H10 THEN   ' see if BL reg changed
  634.         VidType = 3    ' EGA (not sure why it couldn't be VGA too!)
  635.         EXIT FUNCTION
  636.     END IF
  637.  
  638.     VidType = 99      ' other (probably CGA or MDA)
  639.  
  640. END IF
  641.  
  642. END FUNCTION
  643.  
  644.